var override_xhr_buscar_proveedor = false;
	xhr_buscar_proveedor = {
		active : false,
		control_id : []
	};

(function($){
	var defaults = {
		//EVENTOS
		'trigger':'autocomplete', 	//'blur' 'change' 'none'  evento que lanza la búsqueda de datos
		'trigger_onload':false,		//true	realiza búsqueda inicial en caso que exista valor en el recuadro (util para paginas edit y add cuando tiene error)
		'search_modal':true,			//false		utilizar ventana modal para búsqueda de proveedor
		//UI input
		'search_button':'search.png', 		//usar icono para ventana de búsqueda de datos
		'search_button_pos':'after',		//'before'	posición del icono de búsqueda
		//AJAX
		'aditional_parameters':{},	//parametros adicionales para el envio de datos
		'url':_WEB_ROOT + 'proveedores/buscar',	//url de busqueda de proveedores
		'method':'post',			//'get'
		'clear_on_empty':false, 		//limpiar datos en caso que el input principal esté en blanco
		'clear_on_error':true, 		//limpiar datos en caso de error
		//'conditions':function(){return true},	//funcion de validación previa a envio de datos
		//SEARCH window
		'search_window_title':'Buscar Proveedor',	//título de ventana modal
		'search_window_display_fields':{'display':'','title':''},		//campos para llenar la lista de la ventana modal  {'display':'[Modelo.campo2] [Modelo.campo3]', 'title':''}
		'modal':true,				//true bloquear ui
		'position':'center',		//'center','left','right','top','bottom' ['right','top'] [0,123] jQuery Dialog position
		'zIndex':1000,
		//AUTOCOMPLETE
		'minlength':3,				//longitud mínima para empezar a buscar por autocompletado
		'maxitems':10,				//cantidad máxima de resultados para el autocompletado
		//UI output
		'fill_fields':{},		//llenar otros campos	{'CampoId1':'Modelo.campo1', 'CampoId2':'Modelo.campo2 Modelo2.campo1'}
		'loader_pos':'next', 		//'before','class','none'    posición del loader al cargar ajax.
		'loader':'ajax1.gif',  		//'clase',	//muestra la imagen loader o usa una clase mientras se carga...
		'callback':'',			//funcion que se ejecutará después de cargar los datos seleccionados
		'error_callback':'',	//funcion que se ejecutará antes de las acciones de error.
		'on_empty':'',			//funcion que se ejecutará en caso que el resultado de ajax sea ''
		'dialog_callbacks':{	//funciones que se ejecutarán para el díalogo
			'onShow':'',		//funcion que se ejecuta al cargar el dialogo
			'onLoad':'',		//funcion que se ejecuta cuando se cargan los datos ajax
			'onHide':''			//funcion que se ejecuta cuando se oculta el diálogo
		}
	};
	
	$.fn.buscarProveedor = function(action, options){
		if(typeof(action) == 'object'){
			options = action;
			action = 'initialize';
		}
		
		switch(action){
			case 'initialize': //inicializar
				return this.filter(':not(.has_buscar_proveedor)')
				.addClass('has_buscar_proveedor')
				// .bind('change.valor_blanco', function(){
					// el = $(this);
					// opts = el.data('buscar_proveedor:options');
					// if(el.val().trim() == ''){
						// clear_fields(el);
					// }
				// })
				// .bind('keypress.escape', function(e){
					// el = $(this);
					// tecla = (document.all) ? e.keyCode : e.which;
					// switch(tecla){
						// case '13':
							// return false;
							// break;
						// case '27':
							// break;
					// }
				// })
				.bind('focus.buscar_proveedor.last_value', function(){
					states = $(this).data('buscar_proveedor:states');
					states.valor_previo = $(this).val();
					$(this).data('buscar_proveedor:states', states);
				})
				.bind('focusout.buscar_proveedor.check_empty', function(){
					el = $(this);
					opts = el.data('buscar_proveedor:options');
					if(opts.clear_on_empty && !this.value.trim().length){
						el.buscarProveedor('clear_results');
					}
				})
				.each(function(){
					el = $(this);
					setOptions(el);
					opts = el.data('buscar_proveedor:options');
					
					if(opts.search_modal === true && jQuery().dialog){
						if(check_display_fields(el)){
							add_search_button(el);
						} else {
							show_error(el, 'no se establecieron los campos para mostrar en la ventana modal');
						}
					}
					
					//verificando evento que realizará la búsqueda sobre el control
					switch(opts.trigger){
						case 'blur':
						case 'change':
							add_search_blur_change(el);
							break;
						case 'autocomplete':
							add_auto_complete(el);
							break;
						case 'none':
						default:
							//no hace ninguna peticion del recuadro original
					}
					
					//realizando búsqueda inicial en caso que sea una pagina de edición o se hayan recargado los datos
					if(opts.trigger_onload && el.val()){
						el.trigger(opts.trigger);
					}
				}).end()
				break;
			case 'enable_blur_change':
				enable_blur_change($(this));
				$(this).addClass('has_buscar_proveedor').next('img[class*=buscar_proveedor]').show();
				break;
			case 'enable_autocomplete':
				$(this).addClass('has_buscar_proveedor').next('img[class*=buscar_proveedor]').show();
				enable_autocomplete($(this));
				break;
			case 'disable_blur_change':
				disable_blur_change($(this));
				$(this).removeClass('has_buscar_proveedor').next('img[class*=buscar_proveedor]').hide();
				break;
			case 'disable_autocomplete':
				$(this).removeClass('has_buscar_proveedor').next('img[class*=buscar_proveedor]').hide();
				disable_autocomplete($(this));
				break;
			case 'clear_results':
				clear_fields($(this));
				break;
		}
		
		function show_error(el, msg){
			if(typeof alerta == 'function'){
				if(el.data('buscar_proveedor:alertaMsg')){
					$.gritter.remove(el.data('buscar_proveedor:alertaMsg'));
				}
				el.data('buscar_proveedor:alertaMsg', alerta(msg, 'ADCSoft::Error'));
			} else {
				alert(msg);
			}
		};
		
		function check_display_fields(el){
			opts = el.data('buscar_proveedor:options');
			c = false;
			for(var i in opts.search_window_display_fields){
				c = true;
				break;
			}
			return c;
		};
		
		function add_search_blur_change(el){
			type = options.trigger + '.buscar_proveedor';
			options = el.data('buscar_proveedor:options');
			
			el.bind(type, function(e){
				e.preventDefault();
				if(el.val().trim().length > 0 && el.val().trim().length >= options.minlength){
					//realizando la búsqueda
					remove_ajax_loader(el);
					append_ajax_loader(el);
					valor = el.val().trim()?el.val():'%';
					search(el, valor, function(data){
						if(data){
							if(!data.Error && data[0]){								
								//seleccionando el primer resultado disponible
								data = data[0];
								setSelectedData(el, data);
								//verificando que fill_fields tenga propiedades
								var c = 0;
								for (var i in opts.fill_fields){
									c=1; break;
								}
								if(c === 0){
									show_error(el, 'No se especificaron campos a llenar');
								} else {
									fill_data(el);
								}
							} else {
								show_error(el, 'No hay resultados');
								if (opts.clear_on_error){
									clear_fields(el);
									removeSelectedData(el);
								}
							}
						}else{
							if(data == '' && opts.on_empty && typeof opts.on_empty == 'function'){
								opts.on_empty(el);
							}
							removeSelectedData(el);
						}
						remove_ajax_loader(el);
						return false;
					});
				} 
				return false;
			});
		};
		
		function add_auto_complete(el){
			options = el.data('buscar_proveedor:options');
			//verificando que el plugin de auto complete existe
			if (typeof jQuery.autoComplete != 'object'){
				show_error(el, 'no se ha cargado el plugin jQuery auto complete');
			} else {
				auto_complete(el);
			}
		};
		
		function auto_complete(el){
			opts = el.data('buscar_proveedor:options');
			postdata = $.extend({}, opts.aditional_parameters, {'autocomplete':1});
			el.autoComplete({
				ajax:opts.url,
				postVar:'q',
				postData:postdata,
				minChars:opts.minlength,
				maxItems:opts.maxitems,
				width:300,
				spinner: function(evt, ui){
					remove_ajax_loader(el);
					append_ajax_loader_to_object(el);
					
					if($.inArray(el.attr('id'), xhr_buscar_proveedor.control_id) == -1){
						xhr_buscar_proveedor.control_id[xhr_buscar_proveedor.control_id.length] = el.attr('id');
					}
					xhr_buscar_proveedor.active = true;
				},
				onSelect:function(evt, ui){
					append_ajax_loader(el);
					search(el, el.val(), function(data){
						if(!data.Error && data[0] && data[0]!='no ha establecido los parámetros correctamente'){
							data = data[0];
							setSelectedData(el, data);
							fill_data(el);
						} else {
							clear_fields(el);
						}
						remove_ajax_loader(el);
					});
				},
				onShow:function(evt, ui){
					//xhr_buscar_proveedor.active = false;
					aux = [];
					for(var i in xhr_buscar_proveedor.control_id){
						if(xhr_buscar_proveedor.control_id[i] != el.attr('id')){
							aux[aux.length] = xhr_buscar_proveedor.control_id[i];
						}
					}
					xhr_buscar_proveedor.control_id = aux;
					buscar_xhr_count();
					
					remove_ajax_loader(el);
				}
			});
		};
		
		function setOptions(el){
			options = $.extend({'xhr':null}, defaults, el.data('buscar_proveedor:options'),options);
						
			el.data('buscar_proveedor:options', options);
			el.data('buscar_proveedor:states', {
				'valor_previo':el.val(),
				'focus':false
			});
		};
		
		function setSelectedData(el, selected_data){
			removeSelectedData(el);
			el.data('buscar_proveedor:selected_data', selected_data);
		};
		
		function getSelectedData(el){
			return el.data('buscar_proveedor:selected_data');
		};
		
		function removeSelectedData(el){
			el.removeData('buscar_proveedor:selected_data');
		};
		
		function add_search_button(el){
			opts = el.data('buscar_proveedor:options');
			//fix para tecla F3
			buttonId = el.attr('id')+'Button';
			el.data('searchButton', buttonId);
			
			$button = $('<img id="'+ buttonId +'" src="'+_WEB_ROOT+'img/'+ opts.search_button +'" width="15" height="15" style="cursor:pointer;width:15px;height:15px;border:none" alt="buscar" title="'+ opts.search_window_title +'" class="buscar_proveedor" />')
				.click(function(){open_search_form(el);});
			switch(opts.search_button_pos){
				case 'after':
					el.after($button);
					break;
				case 'before':
					el.before($button);
					break;
				default:
					el.after($button);	//--> este puede ser cambiado a otro por defecto
			}
		};
		
		function build_select_options(el, data){
			opts = el.data('buscar_proveedor:options');
			display_fields = opts.search_window_display_fields;
			
			title_format = 'title="' + display_fields.title + '"';
			display_format = display_fields.display;
			
			opciones = '';
			for(var i in data){
				opciones += '<option value="'+ i +'" '+ replace_string(data[i], title_format) +'>'+ replace_string(data[i], display_format) +'</option>';
			}
			
			return opciones;
		};
		
		function replace_string(data, replaceable){
			if (!replaceable) return '';
			for(var i in data){
				if(typeof data[i] == 'object' && data[i] != null){
					for(var j in data[i]){
						if(typeof data[i][j] == 'object' && data[i][j] != null){
							for(var k in data[i][j]){
								replaceable = replaceable.replace(i+'.'+j+'.'+k, data[i][j][k]);
							}
						} else {
							replaceable = replaceable.replace(i+'.'+j, data[i][j]);
						}
					}
				} else {
					replaceable = replaceable.replace(i, data[i]);
				}
			}
			return replaceable;
		};
		
		function open_search_form(el){
			opts = el.data('buscar_proveedor:options');
			
			window.d_buscarProveedor = $('<div class="d-header">' + 
				'<input name="data[q]" type="text" value="'+ el.val() +'" style="width: 450px; margin:10px; margin-top: 12px;" id="q">'+
				'<br /><select style="width: 450px; margin:10px; margin-top:0px;" id="resultados" size="5" name="list"></select>'+
			  '</div>')
			.dialog({
				title:opts.search_window_title,
				width:500,
				height:250,
				hide:'slide',
				resizable: 'width',
				modal:opts.modal,
				position:opts.position,
				zIndex:opts.zindex,
				buttons:{
					'Cerrar':function(){
						$(this).dialog('close');
					},
					'Buscar':function(){
						$dialog = $(this);
						//restableciendo datos del resultado de busqueda
						$select = $(this).find('select#resultados').addClass('ajax_load2').html('');
						
						//realizando la búsqueda
						append_ajax_loader(el);
						q = $(this).find('#q').val();
						if(q.trim().length === 0){
							q = '%';
						}
						search(el, q, function(data){
							$select.removeClass('ajax_load2');
							if(data){
								if(!data.error && data.length){
									opciones = '';
									opciones = build_select_options(el, data);
									
									$select.html(opciones);
									$select
									.find('option:even').css({'background-color':'#EEEEF0'}).end()
									.find('option').dblclick(function(){
										i = this.value;
										//selected_data = data[i];
										setSelectedData(el, data[i]);
										//verificando que fill_fields tenga propiedades
										var c = 0;
										for (var i in opts.fill_fields){
											c=1; break;
										}
										if(c === 0){
											show_error(el, 'No se especificaron campos a llenar');
										} else {
											fill_data(el);
										}
										$dialog.dialog('close');
									});
									if(opts.dialog_callbacks && typeof opts.dialog_callbacks.onLoad == 'function'){
										opts.dialog_callbacks.onLoad(data, el, $dialog);
									}
								} else if (data.error){
									if(opts.dialog_callbacks && typeof opts.dialog_callbacks.onLoad == 'function'){
										opts.dialog_callbacks.onLoad(data, el, $dialog);
									}
								}
							}
							remove_ajax_loader(el);
						});
						
					}
				},
				open:function(evt, ui){
					$btnbuscar = $('button:contains(Buscar):visible','.ui-dialog-buttonpane');
					// $btnbuscar = $(this).parent().find('button:contains(Buscar)');
					$btncerrar = $('button:contains(Cerrar):visible','.ui-dialog-buttonpane');
					// $btncerrar = $(this).parent().find('button:contains(Cerrar)');
					//si el recuadro de busqueda tiene un valor realizar la búsqueda inmediatamente despues de la carga de la ventana
					if($(this).find('input:text').val().trim().length){
						$btnbuscar.trigger('click');
					}
					$(this)
						//agregando sombreado a ventana
						.parent().css({
							'-moz-box-shadow':'0 0 1em gray',
							'-webkit-box-shadow':'0 0 1em gray',
							'box-shadow':'0 0 1em gray'
						}).end()
						//al presionar enter realice la busqueda
						.find('input:text').focus()
							.keyup(function(e){
								var k;
								if (window.event == undefined) k=e.which;
								else k=e.keyCode;
								
								switch(k){
									case 13:
										$btnbuscar.trigger('click');
										break;
									case 40:
										$(this).siblings('select#resultados').focus();
										break;
								}
						}).end()
						.find('select#resultados')
							.keyup(function(e){
								var k;
								if (window.event == undefined) k=e.which;
								else k=e.keyCode;
								
								switch(k){
									case 13:
										$(this).find('option:selected').trigger('dblclick');
										break;
								}
							});
					//agregando icono a los botones cerrar y buscar
					// $btncerrar.button("option","icons",{primary:'ui-icon-cancel'});
					// $btnbuscar.button("option","icons",{primary:'ui-icon-search'});
					if(!$btncerrar.find('span.ui-icon').length){
						$btncerrar.prepend('<span style="float:left;margin-right:10px" class="ui-icon ui-icon-cancel" />');
					}
					
					if(!$btnbuscar.find('span.ui-icon').length){
						$btnbuscar.prepend('<span style="float:left;margin-right:10px" class="ui-icon ui-icon-search" />');
					}
					if(opts.dialog_callbacks && typeof opts.dialog_callbacks.onShow == 'function'){
						opts.dialog_callbacks.onShow(el, $(this));
					}
				},
				close:function(){
					el.focus();
					if(opts.dialog_callbacks && typeof opts.dialog_callbacks.onHide == 'function'){
						opts.dialog_callbacks.onHide(el, $(this));
					}
					//eliminar la ventana del DOM
					$(this).remove();
				}
			});
			
			
		};
		
		function disable_blur_change(el){
			opts = el.data('buscar_proveedor:options');
			if(opts && el.hasClass('has_buscar_proveedor')){
				trigger = opts.trigger; // + '.buscar_proveedor';
				event = '';
				lista = el.data('events')[trigger];
				for(var i =0, j=lista.length; i<j; i++){
					if(lista[i].namespace == 'buscar_proveedor'){
						event = lista[i].handler;
						el.unbind(trigger + '.buscar_proveedor');
						break;
					}
				}
				el.data('buscar_proveedor:disabled_event', event);
			}
		}
		
		function enable_blur_change(el){
			opts = el.data('buscar_proveedor:options');
			if(opts && !el.hasClass('has_buscar_proveedor')){
				trigger = opts.trigger;
				event = el.data('buscar_proveedor:disabled_event');
				el.bind(trigger + '.buscar_proveedor', event);
			}
		}
		
		function disable_autocomplete(el){
			opts = el.data('buscar_proveedor:options');
			if(opts && el.hasClass('has_buscar_proveedor')){
				el.autoComplete('disable');
			}
		};
		
		function enable_autocomplete(el){
			opts = el.data('buscar_proveedor:options');
			if(opts && !el.hasClass('has_buscar_proveedor')){
				el.autoComplete('enable');
			}
		};
		
		function cancel_search(el){
			if(el.data('buscar_proveedor:xhr')){
				xhr = el.data('buscar_proveedor:xhr');
				xhr.abort();
				
				aux = [];
				for(var i in xhr_buscar_proveedor.control_id){
					if(xhr_buscar_proveedor.control_id[i] != el.attr('id')){
						aux[aux.length] = xhr_buscar_proveedor.control_id[i];
					}
				}
				xhr_buscar_proveedor.control_id = aux;
				buscar_xhr_count();
			}
		};
		
		function search(el, query, callback){
			opts = el.data('buscar_proveedor:options');
			data = $.extend({}, opts.aditional_parameters, {'q': query});
			cancel_search(el);
			el.data('buscar_proveedor:xhr', $.ajax({
					'url': opts.url,
					'type': opts.method,
					'data': data,
					'dataType': 'json',
					//'async': false,
					'error': function(){
						if(opts.error_callback && typeof opts.error_callback == 'function'){
							opts.error_callback(el);
						}
						show_error(el, 'Hubo un error al buscar datos');
						if (opts.clear_on_error){
							clear_fields(el);
							removeSelectedData(el);
						}
						// xhr_buscar_proveedor.active = false;
						// xhr_buscar_proveedor.control_id = '';
						aux = [];
						for(var i in xhr_buscar_proveedor.control_id){
							if(xhr_buscar_proveedor.control_id[i] != el.attr('id')){
								aux[aux.length] = xhr_buscar_proveedor.control_id[i];
							}
						}
						xhr_buscar_proveedor.control_id = aux;
						buscar_xhr_count();
					},
					'beforeSend':function(){
						// xhr_buscar_proveedor.active = true;
						// xhr_buscar_proveedor.control_id = el.attr('id');
						if($.inArray(el.attr('id'), xhr_buscar_proveedor.control_id) == -1){
							xhr_buscar_proveedor.control_id[xhr_buscar_proveedor.control_id.length] = el.attr('id');
						}
						xhr_buscar_proveedor.active = true;
					},
					'complete':function(){
						// xhr_buscar_proveedor.active = false;
						// xhr_buscar_proveedor.control_id = '';
						aux = [];
						for(var i in xhr_buscar_proveedor.control_id){
							if(xhr_buscar_proveedor.control_id[i] != el.attr('id')){
								aux[aux.length] = xhr_buscar_proveedor.control_id[i];
							}
						}
						xhr_buscar_proveedor.control_id = aux;
						buscar_xhr_count();
					},
					'success': callback
				})
			);
		};
		
		function get_data_long_names(el){
			data = el.data('buscar_proveedor:selected_data');
			test = {};
			for(var i in data){
				if(typeof data[i] == 'object' && data[i] != null){
					for(var j in data[i]){
						if(typeof data[i][j] == 'object' && data[i][j] != null){
							for(var k in data[i][j]){
								test[i+'.'+j+'.'+k] = data[i][j][k];
							}
						} else {
							test[i+'.'+j] = data[i][j];
						}
					}
				} else {
					test[i] = data[i];
				}
			}
			return test;
		}
		
		function fill_data(el){
			data = el.data('buscar_proveedor:selected_data');
			//data = selected_data;
			clear_fields(el);

			//creando un objeto con los nombres largos...
			//pej. Proveedore.codigo
			test = get_data_long_names(el);

			opts = el.data('buscar_proveedor:options');
			//el.val(data.Proveedore.codigo);
			
			//obteniendo una copia de la lista de objetos a llenar
			campos = $.extend({},opts.fill_fields);
			
			//llenando campos de página principal
			f2 = campos;
			_c = true;
			for(var i in f2){
				change_test = f2[i];
				for(var j in test){
					f2[i] = f2[i].replace(j, test[j]);
				}
				
				//verificando si el valor del input cambió
				if(f2[i] == change_test){
					f2[i] == '';
				}
				try{					
					if(f2[i] == 'null' || f2[i] == change_test) {f2[i]='';}
					$obj = $('#'+i);
					//verificando si es objeto de formulario u objeto html
					if($obj[0].type  == 'checkbox' || $obj[0].type == 'text' || $obj[0].type == 'textarea' || $obj[0].type == 'select-one' || $obj[0].type == 'hidden' || $obj[0].type == 'select-multiple'){
						$obj.val(f2[i]);
					} else {
						$obj.text(f2[i]);
					}					
				} catch(err) {
					_c = false;
					show_error(el, 'no se pudo asignar valor en ' +i,'error');
				}				
			}
			//alert(typeof(el.callback));
			if(_c && typeof(opts.callback) == 'function'){
				opts.callback(data, el);	
			}
			
		};
		
		function clear_fields(el){
			opts = el.data('buscar_proveedor:options');
			if(opts && el.hasClass('has_buscar_proveedor')){
				fields = opts.fill_fields;
				for(var i in fields){
					try{
						obj = $('#'+i);
						if('select-one select-multiple'.lastIndexOf(obj[0].type)>-1){
							//seleccionando la primera opcion
							obj.val(0);
						} else {
							obj.val('').text('');
						}
					} catch(err) {
						show_error(el, 'no se pudo ubicar el objeto: ' + i);
					}
				}
			}
		};
		
		function append_ajax_loader(el){
			opts = el.data('buscar_proveedor:options');
			objs = '';
			
			//obteniendo lista de objetos, exeptuando los ocultos al usuario
			for(var i in opts.fill_fields){
				objs += '#'+ i + ':visible,';
			}
			$objs = $(objs);
			
			
			$loader = '<img class="buscar_proveedor_loader" src="'+_WEB_ROOT+'img/'+ opts.loader +'" alt="..." />';
			switch(opts.loader_pos){
				case 'none':
					//no se agrega loader
					break;
				case 'before':
					$objs.before($loader);
					break;
				case 'class':
					$objs.addClass(opts.loader);
					break;
				case 'next':
				default:
					$objs.after($loader);
			}
		};
		
		function append_ajax_loader_to_object(el){
			opts = el.data('buscar_proveedor:options');
			el.after('<img class="buscar_proveedor_loader" src="'+_WEB_ROOT+'img/'+ opts.loader +'" alt="..." />');
		};
		
		function remove_ajax_loader(el){
			opts = el.data('buscar_proveedor:options');
			$('img.buscar_proveedor_loader').remove();
			$('.'+ opts.loader).removeClass(opts.loader);
		};
		
		return this;
	}
})(jQuery);

function validar_ajax_buscar_proveedor(){
	buscar_xhr_count();
	if(xhr_buscar_proveedor && xhr_buscar_proveedor.active && !override_xhr_buscar_proveedor){
		if(!$('div.gritter-item:contains(Hay una llamada remota en progreso)').length){
			if(window['alertaBuscarProveedor']){
				$.gritter.remove(window['alertaBuscarProveedor']);
			}
			window['alertaBuscarProveedor']=alerta('Hay una llamada remota en progreso','ADCSoft::Validacion','Critical');
		}
		return false;
	}
}

function buscar_xhr_count(){
	xhr_buscar_proveedor.active = xhr_buscar_proveedor.control_id.length?true:false;
}

$(function(){
	$('form').bind('submit.validar_ajax_buscar_proveedor',validar_ajax_buscar_proveedor);
	
	$('input:submit[value=Guardar]').bind('click.validar_ajax_buscar_proveedor',validar_ajax_buscar_proveedor);
});